#!/usr/bin/python3
# -*- coding: utf-8; tab-width: 4; indent-tabs-mode: t -*-

# Copyright (c) 2005-2014 Fpemud <fpemud@sina.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import os
import sys
import strict_hwcfg


def usage():
    print('Usage:')
    print('   test list-devices')
    print('   test list-connectors')
    print('   test device INDEX set [--name=NAME]')
    print('   test connector INDEX set [--name=NAME]')
    print('')
    print('   test list-components [--verbose]')
    print('   test component INDEX list-devices')
    print('   test component INDEX list-connectors')
    print('   test component INDEX set [--name=NAME]')
    print('   test component INDEX device INDEX set [--name=NAME]')
    print('   test component INDEX connector INDEX set [--name=NAME]')
    print('')
    print('   test add-dumb-component [--id component-id] [--vendor VENDOR] [--model MODEL] [--type TYPE] [--name=NAME] [--is-peripheral=true|false]')
    print('   test del-component INDEX')
    print('')
    print('   test check')
    print('')


def die(msg):
    print(msg, file=sys.stderr)
    sys.exit(1)


def machineListDevices():
    machine = strict_hwcfg.probe()

    print("Index          Device Id              Name           Status")
    tlist = sorted(machine.get_devices(), key=lambda x: x.get_type())
    for i, d in enumerate(tlist):
        strIndex = str(i)
        strId = d.get_id() if d.get_id() is not None else ""
        strName = d.get_name() if d.get_name() is not None else ""
        strStatus = "Disabled" if d.is_disabled() else ""

        buf = ""
        buf += strIndex
        buf += " " * (15 - len(strIndex))
        buf += strId
        buf += " " * (23 - len(strId))
        buf += strName
        buf += " " * (15 - len(strName))
        buf += strStatus
        print(buf)


def machineSetDevice():
    pass


def machineSetConnector():
    pass


def machineListConnectors():
    machine = strict_hwcfg.probe()

    print("Index          Connector Id           Name           Status")
    tlist = sorted(machine.get_connectors(), key=lambda x: x.get_type())
    for i, x in enumerate(tlist):
        strIndex = str(i)
        strId = x.get_id() if x.get_id() is not None else ""
        strName = x.get_name() if x.get_name() is not None else ""
        strStatus = "Disabled" if d.is_disabled() else ""

        buf = ""
        buf += strIndex
        buf += " " * (15 - len(strIndex))
        buf += strId
        buf += " " * (23 - len(strId))
        buf += strName
        buf += " " * (15 - len(strName))
        buf += strStatus
        print(buf)


def machineListComponents():
    bVerbose = False
    if len(sys.argv) >= 3 and sys.argv[2] == "--verbose":
        bVerbose = True

    machine = strict_hwcfg.probe()

    print("Index Vendor     Model               Component Type         Component Id                                                                       Name           Status")
    tlist = sorted(machine.get_components(), key=lambda x: x.get_type())
    for i, c in enumerate(tlist):
        strIndex = str(i)
        strVendor = c.get_vendor() if c.get_vendor() is not None else "unknown"
        strModel = c.get_model() if c.get_model() is not None else "unknown"
        strType = c.get_type().value
        strId = c.get_id() if c.get_id() is not None else ""
        strName = c.get_name() if c.get_name() is not None else ""

        if c.is_online():
            strStatus = "Online"
        elif c.get_offline_reason() == strict_hwcfg.OfflineReason.REMOVED:
            strStatus = "Removed"
        elif c.get_offline_reason().is_disabled():
            strStatus = "Disabled"
        elif c.get_offline_reason().is_suspended():
            strStatus = "Suspended"
        else:
            strStatus = "Offline"

        buf = ""
        buf += strIndex
        buf += " " * (6 - len(strIndex))
        buf += strVendor
        buf += " " * (11 - len(strVendor))
        buf += strModel
        buf += " " * (20 - len(strModel))
        buf += strType
        buf += " " * (23 - len(strType))
        buf += strId
        buf += " " * (83 - len(strId))
        buf += strName
        buf += " " * (15 - len(strName))
        buf += strStatus
        print(buf)


def doListComponentDevices():
    assert False


def doAddDumbComponent():
    machine = strict_hwcfg.probe()
    c = strict_hwcfg.Component(None, None, None, strict_hwcfg.ComponentType())
    machine.add_component(c)


def doSetComponent():
    assert False


def doSetDevice():
    assert False


def doSetComponentDevice():
    assert False


def doDelComponent():
    assert False


def doDelDevice():
    assert False


def doCheck():
    assert False


if __name__ == '__main__':
    if len(sys.argv) <= 1:
        usage()
        sys.exit(1)

    if sys.argv[1] == "--help":
        usage()
        sys.exit(0)

    if os.getuid() != 0:
        die("You must run this command as root!")

    op = sys.argv[1]
    if op == "list-devices":
        machineListDevices()
    elif op == "list-connectors":
        machineListConnectors()
    elif op == "list-components":
        machineListComponents()
    elif op == "component-list-devices":
        doListComponentDevices()
    elif op == "add-dumb-component":
        doAddDumbComponent()
    elif op == "add-dumb-device":
        doAddDumbDevice()
    elif op == "set-component":
        doSetComponent()
    elif op == "set-device":
        doSetDevice()
    elif op == "set-component-device":
        doSetComponentDevice()
    elif op == "del-dumb-component":
        doDelComponent()
    elif op == "del-dumb-device":
        doDelDevice()
    elif op == "check":
        doCheck()
    else:
        die('Invalid operation.')
